package com.tarena.lbs.test.es.builder;


import com.alibaba.fastjson2.JSON;
import com.tarena.lbs.test.es.pojo.Student;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpHost;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentType;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * 综合测试,es的索引操作与文档操作
 * 为查询准备数据
 */
@Slf4j
public class IndexBuilder {
    private static RestHighLevelClient client;// 初始化你的Elasticsearch客户端
    static {
        // 1. 给我构造一个可以链接 es的客户端
        HttpHost httpHost=new HttpHost("localhost",9200,"http");
        RestClientBuilder restClientBuilder=RestClient.builder(httpHost);
        client=new RestHighLevelClient(restClientBuilder);
    }
    public static void buildData(String indexName,int docCount) throws Exception {
        createIndexIfNotExists(indexName);
        List<Student> students = generateStudents(docCount); // 生成100个学生文档
        indexDocuments(students,indexName); // 将学生文档索引到Elasticsearch中
    }
    private static String MAPPING="{\"properties\":{\"name\":{\"type\":\"text\",\"analyzer\":\"ik_max_word\",\"search_analyzer\":\"ik_smart\"},\"student_no\":{\"type\":\"text\"},\"birthday\":{\"type\":\"date\"},\"location\":{\"type\":\"geo_point\"},\"gender\":{\"type\":\"keyword\"}}}";
    private static void createIndexIfNotExists(String indexName) {
        try{
            boolean exists=false;
            //2. 填写代码 将索引名称 indexName在es中判断是否存在
            GetIndexRequest getIndexRequest=new GetIndexRequest(indexName);
            exists = client.indices().exists(getIndexRequest, RequestOptions.DEFAULT);
            if(exists){
                log.info("索引:{}存在,重置索引",indexName);
                //3. 如果存在先删除索引
                DeleteIndexRequest deleteIndexRequest=new DeleteIndexRequest(indexName);
                client.indices().delete(deleteIndexRequest,RequestOptions.DEFAULT);
            }
            //4. 创建这个索引 要求分片1个 副本 0个 并且使用常量MAPPING设置映射
            CreateIndexRequest createIndexRequest=new CreateIndexRequest(indexName);
            Settings.Builder setting =
                    Settings.builder()
                            .put("number_of_shards", 1)
                            .put("number_of_replicas", 0);
            createIndexRequest.settings(setting);
            createIndexRequest.mapping(MAPPING, XContentType.JSON);
            client.indices().create(createIndexRequest,RequestOptions.DEFAULT);
        }catch (Exception e){
            log.error("测试环境创建索引:{},出现问题",indexName);
            log.error("具体问题:",e);
        }
    }
    private static void indexDocuments(List<Student> students,String indexName) throws Exception {
        //5. 请以学生元素的 学生no 作为doc id 将students中的数据索引到Elasticsearch中
        for (Student student:students) {
            IndexRequest indexRequest=new IndexRequest();
            indexRequest.index(indexName);
            indexRequest.id(student.getStudent_no());
            indexRequest.source(JSON.toJSONString(student),XContentType.JSON);
            client.index(indexRequest,RequestOptions.DEFAULT);
        }
    }
    private static final String[] GENDERS={"男","女"};
    private static final String[] FAMALY_NAMES={"李","王","张","刘","陈","杨","赵","黄","周","吴"};
    private static final String[] NAMES = {
            "小明", "亮亮", "小红", "芳芳", "小刚", "强强",
            "小李", "丽丽", "小王", "巍巍", "小赵", "昭昭",
            "小周", "舟舟", "小吴", "薇薇", "小郑", "珍珍",
            "小张", "章章", "小黄", "煌煌"
    };

    private static List<Student> generateStudents(int docCount) {
        List<Student> students = new ArrayList<>();
        Random random = new Random();
        for (int i = 0; i < docCount; i++){
            String name=FAMALY_NAMES[(int)(Math.random()*FAMALY_NAMES.length)]+NAMES[(int)(Math.random()*NAMES.length)];
            String gender=GENDERS[(int)(Math.random()*GENDERS.length)];
            Student student = new Student(
                    name,
                    "2021000" + i,
                    LocalDate.of(2000 + random.nextInt(20), 1, 1),
                    (39.9042 + random.nextDouble() * 0.1)+","+(116.4074 + random.nextDouble() * 0.1)
                    ,gender);
            students.add(student);
        }
        return students;
    }

    public static void main(String[] args) {
        try {
            buildData("test01",40);
            client.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
